/**
 * Copyright(c) Yystar Technology Co.,Ltd
 * project：feed-poc
 * package：redis
 * fileName：RedisTest.java
 * date：2012-10-22
 */
package com.yystar.redis.util;

import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException;

/**
 * @author wangshiyong
 * @date 2012-11-18
 * @todo The utility for Redis
 * @modify <BR>
 *         1.2012-11-18 wangshiyong Create file.
 */
public class RedisUtil {
	private final static Log log = LogFactory.getLog(RedisUtil.class);
	private static JedisPool JEDIS_POOL;
	
	static {
		init();
	}
	
	/**
	 * Initialized jedis pool
	 */
	private static void init() {
		try {
			JedisPoolConfig config = new JedisPoolConfig();
			config.setMaxActive(1000);
	        config.setMaxIdle(50);
	        config.setMaxWait(5000);
	        config.setTestOnBorrow(true);
	
			String redisUrl = "10.0.2.53";
			int redisPort = 6379;
			String redisPwd = "";
			if (!redisPwd.equals(""))
				JEDIS_POOL = new JedisPool(config, redisUrl, redisPort, 1000, redisPwd);
			else
				JEDIS_POOL = new JedisPool(config, redisUrl, redisPort);
		} catch (JedisConnectionException e) {
			// TODO: handle exception
			log.error("Redis connect fail. The server has not authorization to access redis server.");
		}
	}
	
	/**
	 * Get a jedis instance(default method)
	 * @return
	 */
	public static Jedis getInstance() {
		if (JEDIS_POOL == null) {
			log.warn("Jedis pool is unconnected. Now reconnect it.");
			init();
		}
		return JEDIS_POOL.getResource();
	}
	
	/**
	 * Get a jedis instance and select special DB
	 * @return
	 */
	public static Jedis getInstance(int dbIndex) {
		Jedis jedis = getInstance();
		jedis.select(dbIndex);
		
		return jedis;
	}
	
	/**
	 * Release jedis instance to jedis pool
	 * @param jedis
	 */
	public static void disconnect(Jedis jedis) {
		JEDIS_POOL.returnResource(jedis);
	}
	
	/**
	 * Publish a message into a channel
	 * @param channel
	 * @param message
	 */
	public static void publishMessage(final String channel, final String message) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					Jedis jedis = getInstance();
					jedis.publish(channel, message);
					disconnect(jedis);
				} catch (Exception e) {
					// TODO: handle exception
					log.error("Fail to run a new thread to publish message - " + e.getMessage());
				}
			}
		}).start();
	}
	
	/**
	 * Publish multiple messages according to channel - message
	 * @param publishMap Map< channel, message>
	 */
	public static void publishMessages(final Map<String, String> publishMap) {
		for (final Entry<String, String> entry : publishMap.entrySet()) {
			if (entry == null) continue;
			
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						if (entry.getKey() != null && entry.getValue() != null) {
							Jedis jedis = getInstance();
							jedis.publish(entry.getKey(), entry.getValue());
							disconnect(jedis);
						}
					} catch (Exception e) {
						// TODO: handle exception
						//e.printStackTrace();
						log.error("Fail to run a new thread to publish message - " + e.getMessage());
					}
				}
			}).start();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Jedis jedis = RedisUtil.getInstance(9);
		System.out.println(jedis.dbSize());
		System.out.println("all data:" + jedis.keys("*"));
		System.out.println(jedis.get("Market:190252:H1:H1OU:189570"));
//		System.out.println("certain data:" + jedis.get("AccountInfo:100:1:cABBts0101"));
//		System.out.println("certain data:" + jedis.ttl("AccountInfo:100:2:1"));
		jedis.flushDB();
		RedisUtil.disconnect(jedis);
	}
}
